﻿namespace Warehouse

open System
open System.Collections.Generic
open System.IO
open System.Configuration
open System.ComponentModel
open Microsoft.FSharp.Reflection

module Monsoon = 

    let rootFolder = 
        let folder = DirectoryInfo(path = ConfigurationManager.AppSettings.["MonsoonFolder"])
        folder.Create()
        folder

    let archiveFolder = rootFolder.CreateSubdirectory "Archive"
    let orderExportDoneFolder = rootFolder.CreateSubdirectory "OrderExportDone"

    let verifyDestinationFolder() = 
        rootFolder.Exists && archiveFolder.Exists && orderExportDoneFolder.Exists

    let getHeaders<'Record> = 
        typeof<'Record> 
        |> FSharpType.GetRecordFields 
        |> Array.map(fun x -> 
            match x.GetCustomAttributes(typeof<DisplayNameAttribute>, true) with
            | [| :? DisplayNameAttribute as header |] -> header.DisplayName
            | _ -> x.Name
        ) 
        |> String.concat "\t"

    let getLine x = 
        x |> FSharpValue.GetRecordFields |> Array.map(function | :? Lazy<string> as v -> v.Value | v -> string v) |> String.concat "\t"

    let getFileName<'Record> name = 
        let fileName = sprintf "%s.%s.txt" name (DateTime.Now.ToString("yyyyMMdd-HHmmss"))
        match rootFolder.GetFiles(fileName) with
        | [| file |] -> file.FullName
        | _ -> 
            let fullName = Path.Combine(rootFolder.FullName, fileName)
            let headers' = getHeaders<'Record>
            File.WriteAllLines(fullName, [ headers' ])
            fullName
        
    let save<'Record> name (records : 'Record[]) = 
        assert FSharpType.IsRecord typeof<'Record>
        if records.Length > 0 
        then
            let lines = Array.map getLine records
            let fullFileName = getFileName<'Record> name
            File.AppendAllLines(fullFileName, lines)
            File.Copy(fullFileName, Path.Combine(archiveFolder.FullName, Path.GetFileName(fullFileName)))

    type QuantityChange = 
        {
            UserData5 : string Lazy
            MonsoonOP : char
            SKU : string
            Quantity : int
        }

    type PriceChange = 
        {
            MonsoonOP : char
            SKU : string
            [<DisplayName("UserData1")>] ShopCost : decimal
            [<DisplayName("UserData2")>] ExtendedPrice : decimal
            [<DisplayName("UserData3")>] SalePrice : decimal
            [<DisplayName("UserData4")>] Shipping : decimal
            CostOfGoods : decimal
        }

    type NewProduct = 
        {
            MonsoonOP : char
            Category : string
            Classification : string
            Brand : string
            Size : string
            Title : string
            SKU : string
            UPC : string
            EAN : string 
            NonStandard : string
            [<DisplayName("UserData1")>] ShopCost : decimal
            [<DisplayName("UserData2")>] ExtendedPrice : decimal
            [<DisplayName("UserData3")>] SalePrice : decimal
            [<DisplayName("UserData4")>] Shipping : decimal
            CostOfGoods : decimal
            Price : decimal Nullable
        }

    let quantityChange xs = save<QuantityChange> "Quantity Change" xs
    let newProduct x = save<NewProduct> "New product inventory Export" [|x|]
    let priceChange x = save<PriceChange> "Updated Price" [|x|]


